import java.util.ArrayList;

public class Tablero {

	private final int numeroJugadores;	
	private final int[] valorFichaLongitud = {7,5,3};
	private final int valorFichaRegiones = 5;
	private final int valorFichaTotalRegiones = 10;
	private final int valorFichaFin = 10;
	
	// mapa
	private ArrayList<Region> regiones;
	private ArrayList<Ruta> rutas;

	// cartas
	private Mazo mazo;
	private MazoVisible cuadrilla;
	private Mazo descarte;

	// fichas
	private ArrayList<FichaLongitud> premiosLong;
	private ArrayList<FichaRegiones> premiosReg;
	private ArrayList<FichaTotalRegiones> premiosTotReg;
	private ArrayList<FichaFin> premiosFin;

	// por ahora crear hardcodeado las ciudades y los mazos
	public Tablero(int numeroJugadores) {
		this.numeroJugadores = numeroJugadores;

		// crea el mapa
		this.cargarMapa();
		// crea las cartas y el mazo
		this.cargarMazo();

		// se mezcla el mazo
		this.mazo.mezclar();

		//inicializa el mazo de descarte
		this.descarte = new Mazo();
		
		// se arma la cuadrilla
		this.cargarCuadrilla();
		
		this.crearFichas();
	}
	
	//GETTERS
	public ArrayList<Region> getRegiones() {
		return this.regiones;
	}

	public ArrayList<Ruta> getRutas() {
		return this.rutas;
	}
	
	public Mazo getMazo(){
		return this.mazo;
	}
	
	public ArrayList<Carta> getCuadrilla() {
		return this.cuadrilla.getCartas();
	}

	public Mazo getDescarte(){
		return this.descarte;
	}
	
	public ArrayList<FichaLongitud> getPremiosLong(){
		return this.premiosLong;
	}
	
	public ArrayList<FichaRegiones> getPremiosReg(){
		return this.premiosReg;
	}
	
	public ArrayList<FichaTotalRegiones> getPremiosTotReg(){
		return this.premiosTotReg;
	}
	
	public ArrayList<FichaFin> getPremiosFin(){
		return this.premiosFin;
	}
	
	//GETTERS AUXILIARES
	public ArrayList<Ciudad> getCiudades() {
		ArrayList<Ciudad> ciudades = new ArrayList<Ciudad>();
		for (Region r : this.regiones) {
			ciudades.addAll(r.getCiudades());
		}

		return ciudades;
	}
	
	//METODOS
	public boolean sonLimitrofe(Ciudad ciudad1, Ciudad ciudad2) {
		for(Ruta r : this.rutas){
			if(r.uneCiudades(ciudad1, ciudad2))
				return true;
		}
		return false;
	}
	
	public int cantidadCiudades(){
		return this.getCiudades().size();
	}
	
	public Carta sacarCartaMazo() {
		//si el mazo esta vacio se toma el descarte y se pasa al mazo y se mezcla
		if(this.mazo.getCartas().isEmpty()){			
			this.renovarMazo();
		}
		return this.mazo.sacar();
	}
	
	private void renovarMazo(){
		this.mazo.agregarCartas(this.descarte.cartas);
		this.descarte.getCartas().clear();
		this.mazo.mezclar();
	}
	
	public Carta sacarCartaCuadrilla(int posicion) {
		Carta c = this.cuadrilla.getCarta(posicion);
		this.cuadrilla.ponerCarta(posicion, this.mazo.sacar());
		return c;
	}
	
	//metodo que envia las cartas de la cuadrilla a descarte y saca 6 nuevas del mazo
	public void renovarCuadrilla(){
		this.descarte.agregarCartas(this.getCuadrilla());
		this.cargarCuadrilla();
	}
	
	//METODOS PRIVADOS
	private void cargarMapa() {

		// crea la lista de regiones
		this.regiones = new ArrayList<Region>();

		// crea las regiones
		Region norte = new Region("Norte");
		Region noreste = new Region("Noreste");
		Region cuyo = new Region("Cuyo");
		Region este = new Region("Este");
		Region patagonia = new Region("Patagonia");

		// crea las ciudades
		// norte
		Ciudad jujuy = new Ciudad("Jujuy",norte);
		Ciudad salta = new Ciudad("Salta",norte);
		Ciudad tucuman = new Ciudad("Tucuman",norte);
		Ciudad catamarca = new Ciudad("Catamarca",norte);
		Ciudad santiagoDelEstero = new Ciudad("santiagoDelEstero",norte);
		// noreste
		Ciudad formosa = new Ciudad("Formosa",noreste);
		Ciudad chaco = new Ciudad("Chaco",noreste);
		Ciudad santaFe = new Ciudad("Santa Fe",noreste);
		Ciudad entreRios = new Ciudad("Entre Rios",noreste);
		Ciudad corrientes = new Ciudad("Corrientes",noreste);
		Ciudad misiones = new Ciudad("Misiones",noreste);
		// cuyo
		Ciudad sanJuan = new Ciudad("San Juan",cuyo);
		Ciudad sanLuis = new Ciudad("San Luis",cuyo);
		Ciudad laRioja = new Ciudad("La Rioja",cuyo);
		Ciudad mendoza = new Ciudad("Mendoza",cuyo);
		Ciudad cordoba = new Ciudad("Cordoba",cuyo);
		// este
		Ciudad laPampa = new Ciudad("La Pampa",este);
		Ciudad buenosAires = new Ciudad("Buenos Aires",este);
		// patagonia
		Ciudad neuquen = new Ciudad("Neuquen",patagonia);
		Ciudad rioNegro = new Ciudad("Rio Negro",patagonia);
		Ciudad chubut = new Ciudad("Chubut",patagonia);
		Ciudad santaCruz = new Ciudad("Santa Cruz",patagonia);
		Ciudad tierraDelFuego = new Ciudad("Tierra Del Fuego",patagonia);

		// carga de regiones
		// norte
		norte.cargarCiudad(jujuy);
		norte.cargarCiudad(salta);
		norte.cargarCiudad(tucuman);
		norte.cargarCiudad(catamarca);
		norte.cargarCiudad(santiagoDelEstero);
		// noreste
		noreste.cargarCiudad(formosa);
		noreste.cargarCiudad(chaco);
		noreste.cargarCiudad(santaFe);
		noreste.cargarCiudad(entreRios);
		noreste.cargarCiudad(corrientes);
		noreste.cargarCiudad(misiones);
		// cuyo
		cuyo.cargarCiudad(sanJuan);
		cuyo.cargarCiudad(sanLuis);
		cuyo.cargarCiudad(laRioja);
		cuyo.cargarCiudad(mendoza);
		cuyo.cargarCiudad(cordoba);
		// este
		este.cargarCiudad(laPampa);
		este.cargarCiudad(buenosAires);
		// patagonia
		patagonia.cargarCiudad(neuquen);
		patagonia.cargarCiudad(rioNegro);
		patagonia.cargarCiudad(chubut);
		patagonia.cargarCiudad(santaCruz);
		patagonia.cargarCiudad(tierraDelFuego);
		
		//agrego las regiones a la lista
		this.regiones.add(norte);
		this.regiones.add(noreste);
		this.regiones.add(cuyo);
		this.regiones.add(este);
		this.regiones.add(patagonia);
		
		// crea la lista de rutas
		this.rutas = new ArrayList<Ruta>();

		// carga las rutas
		this.rutas.add(new Ruta(jujuy, salta));
		this.rutas.add(new Ruta(salta, formosa));
		this.rutas.add(new Ruta(salta, tucuman));
		this.rutas.add(new Ruta(salta, santiagoDelEstero));
		this.rutas.add(new Ruta(catamarca, tucuman));
		this.rutas.add(new Ruta(catamarca, laRioja));
		this.rutas.add(new Ruta(tucuman, santiagoDelEstero));
		this.rutas.add(new Ruta(santiagoDelEstero, chaco));
		this.rutas.add(new Ruta(chaco, corrientes));
		this.rutas.add(new Ruta(chaco, santaFe));
		this.rutas.add(new Ruta(corrientes, misiones));
		this.rutas.add(new Ruta(corrientes, entreRios));
		this.rutas.add(new Ruta(santaFe, cordoba));
		this.rutas.add(new Ruta(entreRios, buenosAires));
		this.rutas.add(new Ruta(buenosAires, laPampa));
		this.rutas.add(new Ruta(laPampa, cordoba));
		this.rutas.add(new Ruta(laPampa, mendoza));
		this.rutas.add(new Ruta(laPampa, rioNegro));
		this.rutas.add(new Ruta(cordoba, santiagoDelEstero));
		this.rutas.add(new Ruta(laRioja, sanJuan));
		this.rutas.add(new Ruta(laRioja, sanLuis));
		this.rutas.add(new Ruta(mendoza, sanLuis));
		this.rutas.add(new Ruta(mendoza, neuquen));
		this.rutas.add(new Ruta(neuquen, rioNegro));
		this.rutas.add(new Ruta(rioNegro, chubut));
		this.rutas.add(new Ruta(chubut, santaCruz));
		this.rutas.add(new Ruta(santaCruz, tierraDelFuego));
	}

	private void cargarMazo() {
		// crear cartas
		ArrayList<Ciudad> ciudades = this.getCiudades();
		this.mazo = new Mazo();

		// por cada una de las ciudades se cargan 3 cartas al mazo
		for (Ciudad c : ciudades) {
			for (int i = 0; i < 3; i++) {
				this.mazo.agregarCarta(new Carta(c));
			}
		}
	}

	private void cargarCuadrilla() {
		// crea la cuadrilla
		this.cuadrilla = new MazoVisible();

		// saca las primeras 6 cartas y las agrega en la cuadrilla
		for (int i = 0; i < 6; i++) {
			if(this.mazo.getCartas().isEmpty()){			
				this.renovarMazo();
			}
			this.cuadrilla.agregarCarta(this.mazo.sacar());
		}
	}

	private void crearFichas() {
		// crear las fichas de longitud
		this.premiosLong = new ArrayList<FichaLongitud>();	
		for (int i : this.valorFichaLongitud) {
			for (int j = 0; j < (this.numeroJugadores - 1); j++) {
				this.premiosLong.add(new FichaLongitud(i, i));
			}
		}

		// crea las fichas de regiones
		this.premiosReg = new ArrayList<FichaRegiones>();
		for (Region reg : this.regiones) {
			for (int i = 0; i < (this.numeroJugadores - 1); i++) {
				this.premiosReg.add(new FichaRegiones(this.valorFichaRegiones, reg));
			}
		}

		// crea las fichas por total de regiones
		this.premiosTotReg = new ArrayList<FichaTotalRegiones>();
		for (int i = 0; i < (this.numeroJugadores - 1); i++) {
			this.premiosTotReg.add(new FichaTotalRegiones(this.valorFichaTotalRegiones));
		}

		// crea la ficha de fin de juego
		this.premiosFin = new ArrayList<FichaFin>();
		this.premiosFin.add(new FichaFin(this.valorFichaFin));		
	}	
	
}